package com.heima.wemedia.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.green20220302.models.ImageModerationResponseBody;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cjq.apis.article.IArticleClient;
import com.cjq.core.MinioServer;
import com.cjq.green.constant.ImageRiskLevel;
import com.cjq.green.constant.TextRiskLevel;
import com.cjq.green.service.impl.GreenImage;
import com.cjq.green.service.impl.GreenText;
import com.heima.common.exception.CustomException;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.pojos.WmChannel;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmSensitive;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.SensitiveWordGreenServer;
import com.heima.wemedia.mapper.WmChannelMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmSensitiveMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.service.WmNewsAutoScanService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 自媒体文章自动审核服务实现类
 * 提供文章内容与图片的审核、APP端文章保存等功能
 */
@Service
@Slf4j

public class WmNewsAutoScanServiceImpl implements WmNewsAutoScanService {

    @Autowired
    private WmNewsMapper wmNewsMapper;

    @Autowired
    private GreenText greenText;
    @Autowired
    private GreenImage greenImage;

    @Autowired
    private IArticleClient articleClient;

    @Autowired
    private WmChannelMapper wmChannelMapper;

    @Autowired
    private WmUserMapper wmUserMapper;

    @Autowired
    private MinioServer minioServer;
    @Autowired
    private PlatformTransactionManager transactionManager;
    @Autowired
    private WmSensitiveMapper wmSensitiveMapper;

    /**
     * 自管理的敏感词审核
     * @param content
     * @param wmNews
     * @return
     */
    private boolean handleSensitiveScan(String content, WmNews wmNews) {

        boolean flag = true;

        //获取所有的敏感词
        List<WmSensitive> wmSensitives = wmSensitiveMapper.selectList(Wrappers.<WmSensitive>lambdaQuery().select(WmSensitive::getSensitives));
        List<String> sensitiveList = wmSensitives.stream().map(WmSensitive::getSensitives).collect(Collectors.toList());

        SensitiveWordGreenServer wordGreenServer = new SensitiveWordGreenServer();
        wordGreenServer.loadDictionary(sensitiveList);
        List<String> greenList = wordGreenServer.green(content);
        if(!greenList.isEmpty()){
            wmNews.setReason(CollUtil.join(greenList,","));
            wmNews.setStatus(WmNews.Status.FAIL.getCode());
            wmNewsMapper.updateById(wmNews);
            flag = false;
        }
        return flag;
    }
    /**
     * 自媒体文章自动审核主流程
     * @param id 待审核的自媒体文章ID
     * @throws CustomException 当文章不存在时抛出异常
     */
    @Override
    @Async
    @Transactional
    public void autoScanWmNews(Integer id) {
        // 查询自媒体文章
        WmNews wmNews = wmNewsMapper.selectById(id);
        if (wmNews == null) {

            throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        // 提取文章内容和图片
        Map<String, Object> map = handleTextAndImage(wmNews);
        //自管理的敏感词过滤
        boolean isSensitive = handleSensitiveScan((String) map.get("content"), wmNews);
        if(!isSensitive) {
            return;
        }
        // 文章内容审核
        boolean isGreenText = handleGreenText((String) map.get("text"), wmNews);
        if (!isGreenText) {
            return;
        }
        List<String> images = (List<String>) map.get("images");

        // 图片内容审核
        if (images != null && !images.isEmpty()) {
            boolean isGreenImage = handleGreenImage(images, wmNews);
            if (!isGreenImage) {
                return;
            }
        }

        // 保存APP端文章数据
        ResponseResult responseResult = saveAppArticle(wmNews);
        if (!responseResult.getCode().equals(200)) {
            throw new RuntimeException("WmNewsAutoScanServiceImpl-文章审核，保存app端相关文章数据失败");
        }
        // 回填article_id
        wmNews.setArticleId((Long) responseResult.getData());

        // 更新文章审核状态
        wmNews.setStatus(WmNews.Status.PUBLISHED.getCode());
        wmNews.setReason("审核成功");
        wmNewsMapper.updateById(wmNews);
    }

    /**
     * 保存APP端文章数据
     * @param wmNews 自媒体文章对象
     * @return 操作结果响应对象
     */
    private ResponseResult saveAppArticle(WmNews wmNews) {
        ArticleDto dto = new ArticleDto();
        // 属性的拷贝
        BeanUtils.copyProperties(wmNews, dto);
        // 文章的布局
        dto.setLayout(wmNews.getType());
        // 频道信息设置
        WmChannel wmChannel = wmChannelMapper.selectById(wmNews.getChannelId());
        if (wmChannel != null) {
            dto.setChannelName(wmChannel.getName());
        }

        // 作者信息设置
        dto.setAuthorId(wmNews.getUserId().longValue());
        WmUser wmUser = wmUserMapper.selectById(wmNews.getUserId());
        if (wmUser != null) {
            dto.setAuthorName(wmUser.getName());
        }

        // 文章ID设置
        if (wmNews.getArticleId() != null) {
            dto.setId(wmNews.getArticleId());
        }
        dto.setCreatedTime(new Date());

        // 调用文章服务保存接口
        ResponseResult responseResult = articleClient.saveArticle(dto);
        return responseResult;
    }

    /**
     * 图片内容审核
     * @param images 图片URL列表
     * @param wmNews 自媒体文章对象
     * @return 审核结果（true-通过，false-不通过）
     */
    private boolean handleGreenImage(List<String> images, WmNews wmNews) {
        if (images == null || images.isEmpty()) {
            return true;
        }
        StringBuilder reason = new StringBuilder();
        images = images.stream().distinct().collect(Collectors.toList());
        for (String image : images) {
            // 调用图片审核服务
            Map<String, Object> map = greenImage.scan(minioServer.getPublicURL(image));
            if (map == null) {
                throw new CustomException(AppHttpCodeEnum.SERVER_ERROR);
            }
            String riskLevel = (String) map.get("riskLevel");
            List<ImageModerationResponseBody.ImageModerationResponseBodyDataResult> result =
                (List<ImageModerationResponseBody.ImageModerationResponseBodyDataResult>) map.get("result");

            // 高/中风险处理逻辑
            if (Objects.equals(riskLevel, ImageRiskLevel.HIGH.getDescription()) ||
                Objects.equals(riskLevel, ImageRiskLevel.MEDIUM.getDescription())) {
                Iterator<ImageModerationResponseBody.ImageModerationResponseBodyDataResult> iterator = result.iterator();
                if (iterator.hasNext()){
                    reason.append(iterator.next());
                    while (iterator.hasNext()){
                        reason.append(',').append(iterator.next().getDescription());
                    }
                }
                wmNews.setReason(reason.toString());
                wmNews.setStatus(Objects.equals(riskLevel, ImageRiskLevel.HIGH.getDescription()) ?
                    WmNews.Status.FAIL.getCode() : WmNews.Status.ADMIN_AUTH.getCode());
                wmNewsMapper.updateById(wmNews);
                log.warn("图片:{{}}审核不通过,原因:{}", image, reason);
                return false;
            }
        }
        return true;
    }

    /**
     * 文本内容审核
     * @param text 待审核文本内容
     * @param wmNews 自媒体文章对象
     * @return 审核结果（true-通过，false-不通过）
     */
    private boolean handleGreenText(String text, WmNews wmNews) {
        // 合并标题与正文进行审核
        Map<String, String> map = greenText.scan(wmNews.getTitle() + text);
        if (map == null) {
            throw new CustomException(AppHttpCodeEnum.SERVER_ERROR);
        }
        if (map.isEmpty()) {
            return true;
        } else {
            String reason = map.get("reason");
            JSONObject object = JSON.parseObject(reason);

            String rickLevel = object.getString("riskLevel");
            String riskTips = object.getString("riskTips");
            if (rickLevel == null || rickLevel.isEmpty() || riskTips == null || riskTips.isEmpty()) {
                throw new CustomException(AppHttpCodeEnum.SERVER_ERROR);
            }

            // 不同风险等级处理逻辑
            if (Objects.equals(rickLevel, TextRiskLevel.HIGH.getDescription())) {
                wmNews.setStatus(WmNews.Status.FAIL.getCode());
            }
            if (Objects.equals(rickLevel, TextRiskLevel.MEDIUM.getDescription())) {
                wmNews.setStatus(WmNews.Status.ADMIN_AUTH.getCode());
            }
            if (Objects.equals(rickLevel, TextRiskLevel.LOW.getDescription())) {
                return true;
            }
            wmNews.setReason(riskTips);
            wmNewsMapper.updateById(wmNews);
            log.warn("文本内容:{{}}审核不通过,原因:{}", text, riskTips);
            return false;
        }
    }

    /**
     * 提取文章文本与图片内容
     * @param wmNews 自媒体文章对象
     * @return 包含文本内容和图片列表的Map
     */
    private Map<String, Object> handleTextAndImage(WmNews wmNews) {
        StringBuilder text = new StringBuilder();
        List<String> imagesList = new ArrayList<>();

        // 解析内容中的文本和图片
        if (wmNews.getContent() != null && !wmNews.getContent().isEmpty()) {
            List<Map> maps = JSONArray.parseArray(wmNews.getContent(), Map.class);
            for (Map map : maps) {
                if ("text".equals(map.get("type"))) {
                    text.append(map.get("value"));
                }
                if ("image".equals(map.get("type"))) {
                    imagesList.add((String) map.get("value"));
                }
            }
        }

        // 处理封面图片字段
        if (wmNews.getImages() != null && !wmNews.getImages().isEmpty()) {
            String[] split = wmNews.getImages().split(",");
            imagesList.addAll(Arrays.asList(split));
        }

        HashMap<String, Object> resultMap = new HashMap<>();
        resultMap.put("text", text.toString());
        resultMap.put("images", imagesList);
        return resultMap;
    }

}
